package org.example.controller;

import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.example.comfig.Config;
import org.example.common.R;
import org.example.domain.FileEntity;
import org.example.domain.FileInfo;
import org.example.domain.PreviewZipEntity;
import org.example.service.FileService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 文件 Controller
 */

@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {

    private final Config config;
    private final FileService fileService;

    /**
     * 查询文件列表
     * @param path 路径
     * @param name 名称
     */
    @GetMapping("/list")
    public R<Collection<FileEntity>> list(String path, String name) throws ExecutionException, InterruptedException {
        List<FileEntity> fileEntities = StringUtils.isNotEmpty(name) ? fileService.search(path, name) : fileService.getDirectoryFile(path);
        if(!config.isShowHidden()) fileEntities = fileEntities.stream().filter(item -> item.isDrive() || !item.isHidden()).collect(Collectors.toList());
        fileEntities.sort((o1, o2) -> {
            if(o1.isDirectory() && !o2.isDirectory()) return -1;
            if(!o1.isDirectory() && o2.isDirectory()) return 1;
            return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
        });
        return R.ok(fileEntities);
    }

    /**
     * 下载文件
     */
    @GetMapping("/download")
    public void download(String absolutePath, HttpServletResponse response, HttpServletRequest request) throws IOException, ExecutionException, InterruptedException {
        fileService.download(absolutePath, response,request);
    }

    /**
     * 打包下载
     */
    @GetMapping("/downloadZip")
    public void downloadZip(String[] absolutePathList, HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        fileService.downloadZip(absolutePathList, response,false);
        System.out.println("打包下载耗时：" + (System.currentTimeMillis() - start));
    }

    /**
     * 压缩下载
     */
    @GetMapping("/compressedDownloadZip")
    public void parallelZip(String[] absolutePathList, HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        fileService.downloadZip(absolutePathList, response,true);
        System.out.println("压缩下载耗时：" + (System.currentTimeMillis() - start));
    }

    /**
     * 获取文件图标
     */
    @GetMapping("/icon")
    public void icon(String absolutePath, HttpServletResponse response) throws IOException {
        fileService.icon(absolutePath, response);
    }

    /**
     * 预览文件
     */
    @GetMapping("/preview")
    public void preview(String absolutePath, HttpServletResponse response, HttpServletRequest request) throws IOException, ExecutionException, InterruptedException {
        fileService.download(absolutePath, response,request);
    }

    /**
     * 预览压缩包
     * @param absolutePath 压缩包路径
     * @param directoryName 打开压缩包内的目录
     */
    @GetMapping("/previewZip")
    public R<List<PreviewZipEntity>> previewZip(String absolutePath, String directoryName) throws IOException {
        List<PreviewZipEntity> list = fileService.previewZip(absolutePath, directoryName);
        list.sort((o1, o2) -> {
            if(o1.isDirectory() && !o2.isDirectory()) return -1;
            if(!o1.isDirectory() && o2.isDirectory()) return 1;
            return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
        });
        return R.ok(list);
    }

    /**
     * 打开压缩包内文件
     * @param absolutePath 压缩包路径
     * @param fileName 压缩包内文件名
     */
    @GetMapping("/openZipFile")
    public void openZipFile(String absolutePath, String fileName, HttpServletResponse response, HttpServletRequest request) throws IOException {
        fileService.openZipFile(absolutePath, fileName, response, request);
    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public R<Void> upload(@RequestPart("file") MultipartFile file, @RequestParam("absolutePath") String absolutePath) throws IOException {
        if(!config.isEnableUpload()) throw new RuntimeException("上传文件功能已被关闭！");
        if (StringUtils.isEmpty(absolutePath)) throw new RuntimeException("禁止上传到此路径！");
        fileService.upload(file, absolutePath);
        return R.ok();
    }

    /**
     * 属性
     */
    @GetMapping("/info")
    public R<FileInfo> info(String[] absolutePathList) {
        return R.ok(fileService.info(absolutePathList));
    }

    /**
     * 文本
     */
    @GetMapping("/text")
    public R<String> text(String absolutePath) throws IOException {
        return R.ok(fileService.text(absolutePath));
    }

}
